package
{
	import flash.display.Bitmap;
	import flash.events.TimerEvent;
	import flash.media.Sound;
	import flash.utils.Timer;
	
	import starling.core.Starling;
	import starling.display.Image;
	import starling.display.MovieClip;
	import starling.display.Sprite;
	import starling.display.Stage;
	import starling.events.Event;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	import starling.events.TouchPhase;
	import starling.extensions.PDParticleSystem;
	import starling.extensions.ParticleSystem;
	import starling.textures.Texture;
	import starling.utils.deg2rad;
	import starling.utils.rad2deg;
	
	import utils.LayerUtils;
	import utils.LevelConfigXmlUtils;
	import utils.SoundManager;
	
	import view.Battery.BatteryManager;
	import view.Battery.BatteryView;
	import view.Bullet.BulletForTipManager;
	import view.Bullet.BulletForTipView;
	import view.Bullet.BulletManager;
	import view.Bullet.BulletView;
	import view.FireBulletVO;
	import view.Prize.EnergonView;
	import view.Prize.PrizeManager;
	import view.Prize.PrizeView;
	import view.Score.ScoreManager;
	import view.Score.ScoreView;
	import view.SkillBar.BulletBoxView;
	import view.SkillBar.SkillBarManager;
	import view.SkillBar.SkillBarView;
	
	public class InGame extends Sprite
	{
		private var levelConfig:XML;
		private var starlingStage:Touch;
		private var bgImg:Image;
		private var bgm:Sound;
		private var buildPropTimer:Timer;
		private var bulletForTip:BulletForTipView;
		
        /**子弹装载速度，以时间计量*/
		private var reloadSpeed:uint;
        /**定时装载子弹，以避免无间断连发*/
		private var reloadTimer:Timer;
        /**是否装载子弹完毕*/
		private var reloadComplete:Boolean = true;
        /**是否在发射子弹，在这里等价于是否鼠标已经按下*/
		private var isFiring:Boolean = false;
		public function InGame()
		{
			super();
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		private function onAddedToStage(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			init();
		}		
		
		private function init():void{
			reloadSpeed = 400;
			levelConfig = LevelConfigXmlUtils.getInstance().xml;
			PrizeManager.getInstance().start();
			BulletManager.getInstance().start();
			BatteryManager.getInstance().start();
			BatteryManager.getInstance().addBattery();
			ScoreManager.getInstance().start();
			
			addBg();
			addSound();
			
			//定时在舞台上添加道具
			buildPropTimer = new Timer(4000);
			buildPropTimer.addEventListener(TimerEvent.TIMER, buildProp);
			buildPropTimer.start();
			
			stage.addEventListener(Event.ENTER_FRAME, gameLoop);
			stage.addEventListener(TouchEvent.TOUCH, onTouch);
			
			BulletForTipManager.getInstance().start(stage);
			SkillBarManager.getInstance().start(stage);
		}
		
		private function addSound():void
		{
			var resName:String = levelConfig.bgm.@music;
			var soundName:String = resName.substring(0,resName.indexOf(".")); 
			SoundManager.getInstance().playSound(soundName, true, int.MAX_VALUE);
		}
		
		private function addBg():void
		{
			var resName:String = levelConfig.bg.@pic; //从关卡配置中读取资源名字
			var tempName:String = resName.substring(0,resName.indexOf(".")); //类名由资源名字去掉逗号和后缀所得
			bgImg = new Image(Assets.getTexture("Resource_" + tempName));
			LayerUtils.getInstance().baseLayer.addChild(bgImg);
		}
		
		private var firingRad:Number;
		private function onTouch(event:TouchEvent):void
		{
			starlingStage = event.getTouch(stage);
			if(starlingStage.phase == TouchPhase.HOVER || starlingStage.phase == TouchPhase.MOVED){
				rotateBattery();
			}
			if(starlingStage.phase == TouchPhase.BEGAN){
				isFiring = true;
			}else if(starlingStage.phase == TouchPhase.ENDED){
				isFiring = false;
			}
			if(starlingStage.phase == TouchPhase.MOVED){
				isFiring = true;
			}
		}
		
		private function startReloading():void
		{
			reloadComplete = false;
			reloadTimer = new Timer(reloadSpeed,1);
			reloadTimer.addEventListener(TimerEvent.TIMER, gunReloaded);
			reloadTimer.start();
		}
		
		protected function gunReloaded(event:TimerEvent):void
		{
			reloadComplete = true;
		}
		
		private function gameLoop():void
		{
			checkAndFire();
			checkCollision();
			checkPrizeNum();
//			SoundManager.getInstance().playSound("mute", false, int.MAX_VALUE);
		}
		
		private function checkPrizeNum():void{
			if(PrizeManager.getInstance().prizeVec.length >= 10){
				buildPropTimer.stop();
			}else{
				if(!buildPropTimer.running)
					buildPropTimer.start();
			}
		}
		
		private function checkAndFire():void
		{
			if(reloadComplete && isFiring){
                BatteryManager.getInstance().gunBang();
				creatBullet();
			}
			if(!isFiring){
				BatteryManager.getInstance().stopFire();
			}
		}
		
		private function creatBullet():void
		{
			SoundManager.getInstance().playSound("shoot", false, 1, 0, 0.5);
			var x1:Number = Const.BATTERY_X + Const.GUN_LEN * Math.cos(firingRad);
			var y1:Number = Const.BATTERY_Y + Const.GUN_LEN * Math.sin(firingRad);
			var id:uint = Math.ceil(Math.random() * 8);
			BulletManager.getInstance().addBullets(x1,y1,starlingStage.globalX, starlingStage.globalY, BulletForTipManager.getInstance().tipId);
			
			if(FireBulletVO.fireState == FireBulletVO.SKILLBAR_STATE){
				SkillBarManager.getInstance().subBullet(BulletForTipManager.getInstance().tipId);
			}
			if(FireBulletVO.fireState == FireBulletVO.SYSTEM_STATE)
				BulletForTipManager.getInstance().tipId = FireBulletVO.randomId();
			BulletForTipManager.getInstance().showNextBulletTip(BulletForTipManager.getInstance().tipId);
			startReloading();
		}
		
		private function checkCollision():void
		{
			var prizeNum:uint = PrizeManager.getInstance().prizeVec.length;
			var bulletNum:uint = BulletManager.getInstance().bulletVec.length;
			for(var i:int = prizeNum-1;i >= 0; i--){
				var p:PrizeView = PrizeManager.getInstance().prizeVec[i];
				for(var j:int = bulletNum-1; j>=0; j--){
					var bullet:BulletView = BulletManager.getInstance().bulletVec[j]; 
					var root:Sprite = LayerUtils.getInstance().gameLayer;
					var collide:Boolean = p.hitRect.getBounds(root).intersects(bullet.getBounds(root));
					if(collide){
						BulletManager.getInstance().bulletVec.splice(j,1);
						bulletNum --;
						bullet.destroy();
						//能量块的消失
					    p.processEnergon(bullet.bulletId);
						bullet = null;
						if(p.energonVec.length == 0)
							prizeNum --;
					}
				}
			}
		}
		
		private function rotateBattery():void
		{
			var dx:Number = starlingStage.globalX - Const.BATTERY_X;
			var dy:Number = starlingStage.globalY - Const.BATTERY_Y;
			firingRad = Math.atan2(dy,dx);
			if(firingRad > 0 && firingRad <= Math.PI * 0.5) firingRad = 0;
			else if(firingRad > Math.PI * 0.5 && firingRad < 2 * Math.PI) firingRad = -Math.PI;
			BatteryManager.getInstance().gunRotate(firingRad);
		}
		
		private function buildProp(e:TimerEvent):void{
			var list:XMLList = levelConfig.prizeConfig.child("prize");
			var resNum:uint = list.length();
			var id:uint = Math.floor(Math.random() * resNum);
			var px:int;
			var py:int;
			var _angle:Number;
			
			var dir:String = getDirection();
			switch(dir){
				case "left":
					px = 0-100;
					py = Math.random() * Const.HEIGHT;
//					_angle = Math.random() * Math.PI * 2 / 3 + (-Math.PI / 3);
					break;
				case "right":
					px = Const.WIDTH + 100;
					py = Math.random() * Const.HEIGHT;
//					_angle = Math.random() * Math.PI * 2 / 3 + (Math.PI * 2 / 3);
					break;
				case "top":
					px = Math.random() * Const.WIDTH;
					py = 0 - 100;
//					_angle = Math.random() * Math.PI * 2 / 3 + (Math.PI / 6);
					break;
				case "bottom":
					px = Math.random() * Const.WIDTH;
					py = Const.HEIGHT + 100;
//					_angle = Math.random() * Math.PI * 2 / 3 + (-Math.PI * 5/ 6);
					break;
			}
//			PrizeManager.getInstance().addPrize(id, px, py, _angle);
			PrizeManager.getInstance().addPrize(id, px, py);
		}
		
		private function getDirection():String{
			var m:uint = Math.round(Math.random()*3);
			var dir:String = "";
			switch(m){
				case 0:
					dir = "left";
					break;
				case 1:
					dir = "right";
					break;
				case 2:
					dir = "top";
					break;
				case 3:
					dir = "bottom";
					break;
			}
			return dir;
		}
	}
}
